From: Keir Fraser Date: Wed, 24 Oct 2007 09:49:03 +0000 (+0100) Subject: x86, dom0: Allow get idle time stats by mask. X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~14843 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22man:///%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22man:/?a=commitdiff_plain;h=32d2b4dc6df07df75bd64220a827a8b909cb430a;p=xen.git x86, dom0: Allow get idle time stats by mask. Signed-off-by: Kevin Tian --- diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c index b4ab7d4d2c..4d155b0a98 100644 --- a/xen/arch/x86/platform_hypercall.c +++ b/xen/arch/x86/platform_hypercall.c @@ -293,34 +293,44 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op) case XENPF_getidletime: { - uint32_t i, nr_cpus; - uint64_t idletime; + uint32_t cpu; + uint64_t idletime, now = NOW(); struct vcpu *v; + struct xenctl_cpumap ctlmap; + cpumask_t cpumap; XEN_GUEST_HANDLE(uint64_t) idletimes; ret = -ENOSYS; if ( cpufreq_controller != FREQCTL_dom0_kernel ) break; + memset(&ctlmap, 0, sizeof(ctlmap)); + ctlmap.nr_cpus = op->u.getidletime.cpumap_nr_cpus; + ctlmap.bitmap.p = op->u.getidletime.cpumap_bitmap.p; + xenctl_cpumap_to_cpumask(&cpumap, &ctlmap); guest_from_compat_handle(idletimes, op->u.getidletime.idletime); - nr_cpus = min_t(uint32_t, op->u.getidletime.max_cpus, NR_CPUS); - for ( i = 0; i < nr_cpus; i++ ) + for_each_cpu_mask ( cpu, cpumap ) { - /* Assume no holes in idle-vcpu map. */ - if ( (v = idle_vcpu[i]) == NULL ) - break; - - idletime = v->runstate.time[RUNSTATE_running]; - if ( v->is_running ) - idletime += NOW() - v->runstate.state_entry_time; + if ( (v = idle_vcpu[cpu]) != NULL ) + { + idletime = v->runstate.time[RUNSTATE_running]; + if ( v->is_running ) + idletime += now - v->runstate.state_entry_time; + } + else + { + idletime = 0; + cpu_clear(cpu, cpumap); + } ret = -EFAULT; - if ( copy_to_guest_offset(idletimes, i, &idletime, 1) ) + if ( copy_to_guest_offset(idletimes, cpu, &idletime, 1) ) goto out; } - op->u.getidletime.nr_cpus = i; + op->u.getidletime.now = now; + cpumask_to_xenctl_cpumap(&ctlmap, &cpumap); ret = copy_to_guest(u_xenpf_op, op, 1) ? -EFAULT : 0; } break; diff --git a/xen/include/public/platform.h b/xen/include/public/platform.h index 16bf686d4a..3998989e6f 100644 --- a/xen/include/public/platform.h +++ b/xen/include/public/platform.h @@ -174,13 +174,27 @@ struct xenpf_change_freq { typedef struct xenpf_change_freq xenpf_change_freq_t; DEFINE_XEN_GUEST_HANDLE(xenpf_change_freq_t); +/* + * Get idle times (nanoseconds since boot) for physical CPUs specified in the + * @cpumap_bitmap with range [0..@cpumap_nr_cpus-1]. The @idletime array is + * indexed by CPU number; only entries with the corresponding @cpumap_bitmap + * bit set are written to. On return, @cpumap_bitmap is modified so that any + * non-existent CPUs are cleared. Such CPUs have their @idletime array entry + * cleared. + */ #define XENPF_getidletime 53 struct xenpf_getidletime { - /* IN variables. */ - uint32_t max_cpus; + /* IN/OUT variables */ + /* IN: CPUs to interrogate; OUT: subset of IN which are present */ + XEN_GUEST_HANDLE(uint8_t) cpumap_bitmap; + /* IN variables */ + /* Size of cpumap bitmap. */ + uint32_t cpumap_nr_cpus; + /* Must be indexable for every cpu in cpumap_bitmap. */ XEN_GUEST_HANDLE(uint64_t) idletime; - /* OUT variables. */ - uint32_t nr_cpus; + /* OUT variables */ + /* System time when the idletime snapshots were taken. */ + uint64_t now; }; typedef struct xenpf_getidletime xenpf_getidletime_t; DEFINE_XEN_GUEST_HANDLE(xenpf_getidletime_t);